import { Canvas, Director, director, game, JsonAsset, Node, resources, Scene, warn } from "cc";
import { BUILD, DEBUG, DEV, EDITOR } from "cc/env";
import { Playable, playable } from "./framework/Playable.mjs";
import LocalizeManager from "./framework/LocalizeManager.mjs";
import GameConfigManager from "./framework/GameConfigManager.mjs";
import PresetConfigManager from "./framework/PresetConfigManager.mjs";
import ModelModifyConfigManager from "./framework/ModelModifyConfigManager.mjs";
import CameraConfigManager from "./framework/CameraConfigManager.mjs";
enum Audio {
    get = 'sm_get',//获得物品
    load = 'sm_load',//安检屏障下落
    pop = 'sm_pop',//查到物品
    scanning = 'sm_scanning',//查到物品
    voice1 = 'sm_voice1',//走路结束
    voice2 = 'sm_voice2',//生气音频
    walk = 'sm_walk',//走路
    click = 'sm_click',//点击
    switch = 'sm_switch',//镜头放大
    correct = 'sm_correct',//仪器打红圈
    Cry = 'sm_cry',//哭
    WuXiong = 'sm_angry',//捂胸音效
    Scream = 'sm_scream',//刀物品音效
    Frightened = 'sm_frightened',//首个动作
}
export class PlayableSetupConfig {
    public scene: Scene;
    /** 重玩援关闭埋点记录 */
    readonly disableRetryActions: boolean = false;
    /** 关闭诱导，只在非BUILD的时候有效。 */
    readonly disableInduce: boolean = false;

    public initialize(callback: () => void): void {
        this.startSetup().then(() => callback());

        let logicActiveTime: number;
        director.on(Director.EVENT_BEFORE_SCENE_LAUNCH, (scene) => {
            this.scene = scene;
            // this.initSystems();
            logicActiveTime = performance.now();
        });

        director.once(Director.EVENT_AFTER_SCENE_LAUNCH, (scene) => {
            console.log(`active scene nodes use time: ${(performance.now() - logicActiveTime).toFixed(0)} ms`);
            this.startGame();
        });
    }


    public async startSetup(): Promise<void> {
        if (!BUILD)
            if (this.disableInduce) playable.isInduce = false;

        playable.eventSystem.on(Playable.ActiveCanvasEvent, isShow => {
            const canvas = director.getScene().getComponentInChildren(Canvas);
            if (canvas != null) canvas.node.active = isShow;

        });
        playable.eventSystem.once(Playable.RetryEvent, () => playable.enableAction = this.disableRetryActions);
        playable.eventSystem.on(Playable.EndGameEvent, this.onShutdown, this);


        if (DEV || DEBUG) {
            globalThis.gameManager = this;
            game.emit("gameManager", this);
        }

        // 初始化各种配置功能。
        const configFilenames = ["languages", "gameConfig", "presetConfig", "modelModifyConfig", "cameraConfig"];
        const configManagers = [LocalizeManager, GameConfigManager, PresetConfigManager, ModelModifyConfigManager, CameraConfigManager];
        for (let i = 0; i < configManagers.length; i++) {
            const configFilename = `config/${configFilenames[i]}`;
            try {
                const configAsset = await new Promise<JsonAsset>(resolve => resources.load<JsonAsset>(configFilename, (error, data) => resolve(data)));
                if (configAsset != null) configManagers[i].initialize(configAsset);
            } catch (error) {
                warn(error);
            }
        }
        for (let k in Audio) {
            resources.load<JsonAsset>("common/audio/" + Audio[k], (error, data) => {
                // console.log(`load audio ${Audio[k]} success`);
            })
        }
        return playable.initialize("common/audio/");
    }

    public startGame(): void {
        game.pause();
        playable.eventSystem.once(Playable.StartGameEvent, () => game.resume());
        playable.gameReady();
    }

    public onShutdown(): void {
        console.log('game_end');
    }

}

function setupPlayable() {
    const setupConfig = new PlayableSetupConfig();
    game.onPostProjectInitDelegate.add(() => new Promise<void>(resolve => setupConfig.initialize(resolve)));
}

function enablePlayable(): boolean {
    return globalThis.mvPlayable?.enabled ?? globalThis.MV_PLAYABLE ?? true;
}

// DISABLE_PLAYABLE是为了让PT平台在做模板预览的时候，可以直接用项目来渲染，但又不启动素材。
if (!EDITOR && enablePlayable()) {
    setupPlayable();
}